/*
 * Copyright (C) 2017 skydoves
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.skydoves.preferenceroom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class AESEncryption {
    private static final String CHARSET = "UTF-8";
    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/GCM/NoPadding";

    public static String encrypt(String input, String key) {
        String result = null;
        if (input != null && key != null) {
            byte[] crypted;
            try {
                SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET), KEY_ALGORITHM);
                Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
                IvParameterSpec IV = new IvParameterSpec(secretKeySpec.getEncoded(), 0, 16);
                cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, IV);
                crypted = cipher.doFinal(input.getBytes(CHARSET));
            } catch (UnsupportedEncodingException
                    | NoSuchAlgorithmException
                    | InvalidKeyException
                    | InvalidAlgorithmParameterException
                    | NoSuchPaddingException
                    | BadPaddingException
                    | IllegalBlockSizeException e) {
                return input;
            }
            if (crypted != null) {
                result = Base64.encodeToString(crypted, Base64.DEFAULT);
            }
        }
        return result;
    }

    public static String decrypt(String input, String defaultValue, String key) {
        if (input == null || key == null) {
            return defaultValue;
        }
        byte[] output;
        String result;
        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET), KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            IvParameterSpec IV = new IvParameterSpec(secretKeySpec.getEncoded(), 0, 16);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, IV);
            byte[] encrypted1 = Base64.decode(input, Base64.DEFAULT);
            output = cipher.doFinal(encrypted1);
            if (output == null || new String(output, CHARSET).equals("") || new String(output, CHARSET).equals("null")) {
                return defaultValue;
            } else {
                result = new String(output, CHARSET);
            }
        } catch (UnsupportedEncodingException
                | NoSuchAlgorithmException
                | InvalidKeyException
                | InvalidAlgorithmParameterException
                | NoSuchPaddingException
                | BadPaddingException
                | IllegalBlockSizeException
                | IllegalArgumentException e) {
            return defaultValue;
        }
        return result;
    }
}